#ifndef ___procesar_cadenas

#define ___procesar_cadenas 1

#include "pd_pcads.c"
#include <string.h>
#include <stdlib.h>

signed long long determinarToken(const char *);
signed long long determinarNumero(const char *);
int compararCadenas(const char *, const char *);
signed long long siguienteToken(char **);

#define minusculas(X) ((((X) > 96) && ((X) <= 122)) ? ((X) - 32) : (X))

signed long long determinarToken (const char * cadena) {
  if (!cadena) return -99;
  if (strlen(cadena) > 10) return -99;
  if (!(*cadena)) return -99;
  if (!cadena[1]) {
    if ((*cadena > 64) && (*cadena <= 90)) return 64 - *cadena;
    else if ((*cadena > 96) && (*cadena <= 122)) return 96 - *cadena;
    else if ((*cadena >= 48) && (*cadena <= 57)) return *cadena - 48;
    else return -99;
  }
  switch (tolower(*cadena)) {
  case 'a':
    if (compararCadenas(cadena, "abrir")) return TOK_ABRIR;
    if (compararCadenas(cadena, "aleatorio")) return TOK_ALEATORIO;
    if (compararCadenas(cadena, "aleatoria")) return TOK_ALEATORIA;
    if (compararCadenas(cadena, "aleatorios")) return TOK_ALEATORIOS;
    return -99;
  case 'c':
    if (compararCadenas(cadena, "cadena")) return TOK_CADENA;
    if (compararCadenas(cadena, "caracter")) return TOK_CARACTER;
    if (compararCadenas(cadena, "cerrar")) return TOK_CERRAR;
    if (compararCadenas(cadena, "con")) return TOK_CON;
    if (compararCadenas(cadena, "conexion")) return TOK_CONEXION;
    if (compararCadenas(cadena, "conexiones")) return TOK_CONEXIONES;
    return -99;
  case 'd':
    if (compararCadenas(cadena, "datos")) return TOK_DATOS;
    if (compararCadenas(cadena, "de")) return TOK_DE;
    if (compararCadenas(cadena, "desde")) return TOK_DESDE;
    if (compararCadenas(cadena, "disco")) return TOK_DISCO;
    return -99;
  case 'e':
    if (compararCadenas(cadena, "en")) return TOK_EN;
    if (compararCadenas(cadena, "escribir")) return TOK_ESCRIBIR;
    return -99;
  case 'h':
    if (compararCadenas(cadena, "hasta")) return TOK_HASTA;
    return -99;
  case 'i':
    if (compararCadenas(cadena, "ip")) return TOK_IP;
    return -99;
  case 'l':
    if (compararCadenas(cadena, "leer")) return TOK_LEER;
    if (compararCadenas(cadena, "letra")) return TOK_LETRA;
    return -99;
  case 'n':
    if (compararCadenas(cadena, "nulos")) return TOK_NULOS;
    return -99;
  case 'p':
    if (compararCadenas(cadena, "probar")) return TOK_PROBAR;
    if (compararCadenas(cadena, "puerto")) return TOK_PUERTO;
    return -99;
  case 'r':
    if (compararCadenas(cadena, "repetida")) return TOK_REPETIDA;
    return -99;
  case 's':
    if (compararCadenas(cadena, "sector")) return TOK_SECTOR;
    if (compararCadenas(cadena, "sectores")) return TOK_SECTORES;
    return -99;
  case 't':
    if (compararCadenas(cadena, "todo")) return TOK_TODO;
    return -99;
  case 'u':
    if (compararCadenas(cadena, "unica")) return TOK_UNICA;
    if (compararCadenas(cadena, "usar")) return TOK_USAR;
    return -99;
  case 'v':
    if (compararCadenas(cadena, "veces")) return TOK_VECES;
    return -99;
  default:
    return determinarNumero(cadena);
  }
}

signed long long determinarNumero (const char * cadena) {
  signed long long num = 0;
  for (; *cadena; cadena ++)
    if ((*cadena >= 48) && (*cadena <= 57)) {
      num *= 10;
      num += *cadena - 48;
    } else return -99;
  return num;
}

int compararCadenas (const char * c1, const char * c2) {
  for (; *c1 && *c2; c1 ++, c2 ++)
    if (minusculas(*c1) != minusculas(*c2)) return 0;
  return !(*c1 || *c2);
}

signed long long siguienteToken (char ** pCadena) {
  if (!pCadena || !(*pCadena)) return -98;
  char * posicion = strchr(*pCadena, ' ');
  char * tokenActual = malloc(15);
  signed long long valor;
  if (!posicion) {
    if (strlen(*pCadena) > 14) return -99;
    strcpy(tokenActual, *pCadena);
    *pCadena = NULL;
    posicion = strchr(tokenActual, '\n');
    if (posicion) *posicion = 0;
  } else {
    int cantidad = posicion - *pCadena;
    strncpy(tokenActual, *pCadena, cantidad);
    tokenActual[cantidad] = 0;
    while (*posicion == ' ') posicion ++;
    *pCadena = posicion;
  }
  valor = determinarToken(tokenActual);
  free(tokenActual);
  return valor;
}

#endif